package com.chenyue.cm.moudules.system.controller;

import com.alibaba.fastjson.JSON;
import com.chenyue.cm.base.aop.Log;
import com.chenyue.cm.base.bean.PageVo;
import com.chenyue.cm.base.bean.Pageable;
import com.chenyue.cm.bean.SelectVo;
import com.chenyue.cm.bean.Success;
import com.chenyue.cm.common.utils.RequestUtil;
import com.chenyue.cm.common.utils.StringUtils;
import com.chenyue.cm.moudules.system.service.SysMenusService;
import com.chenyue.cm.moudules.system.service.SysRoleMenusService;
import com.chenyue.cm.moudules.system.service.SysRolesService;
import com.chenyue.cm.moudules.system.utils.CmTreeUtils;
import com.chenyue.cm.system.domain.*;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.github.xiaoymin.knife4j.annotations.ApiSort;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;

@Controller
@RequestMapping("/sysRoles")
@Api(value = "系统管理-角色", tags = "系统管理-角色")
@ApiSort(2)
public class SysRolesController {

    private final SysRolesService sysRolesService;

    private final SysRoleMenusService sysRoleMenusService;

    private final SysMenusService sysMenusService;


    public SysRolesController(SysRolesService sysRolesService, SysRoleMenusService sysRoleMenusService, SysMenusService sysMenusService) {
        this.sysRolesService = sysRolesService;
        this.sysRoleMenusService = sysRoleMenusService;
        this.sysMenusService = sysMenusService;
    }

    /**
     * 【API】-----【S2001】
     * 获取角色列表分页数据
     *
     * @param request page
     * @return Success
     * @author chenyue
     */
    @RequestMapping("/getList")
    @ResponseBody
    @ApiOperation(value = "【S2001】获取角色列表(带分页)", notes = "获取角色列表信息，带分页数据")
    @ApiOperationSupport(order = 1)
    @ApiImplicitParams({
            @ApiImplicitParam(value = "pageSize", name = "pageSize", dataType = "int", required = true),
            @ApiImplicitParam(value = "offset", name = "offset", dataType = "int"),
            @ApiImplicitParam(value = "pageNum", name = "pageNum", dataType = "int"),
    })
    @Log(value = "查询角色列表信息", type = "1")
    public Success getList(HttpServletRequest request) {
        Pageable pageInfo = RequestUtil.getPageable(request);
        PageVo<SysRoles> result = sysRolesService.getPageBean(pageInfo, SysRoles.class);
        return Success.success(result);
    }

    /**
     * 【API】-----【S2002】
     * 获取用户角色下拉列表（渲染下拉框）
     *
     * @return List<SelectVo>
     */
    @PostMapping("/getRolesList")
    @ResponseBody
    @ApiOperation(value = "【S2002】获取角色列表(下拉列表)", notes = "获取角色列表信息，渲染下拉列数据")
    @ApiOperationSupport(order = 2)
    @Log(value = "查询角色列表信息（下拉）", type = "1")
    public List<SelectVo> getRolesSelectList() {
        List<SelectVo> resultList = new ArrayList<>();

        List<SysRoles> result = sysRolesService.getBaseDao().selectList(null);
        for (SysRoles sysRoles : result) {
            resultList.add(new SelectVo(sysRoles.getRoleName(), sysRoles.getId()));
        }

        return resultList;
    }


    /**
     * 【API】-----【S2003】
     * 保存角色信息
     *
     * @param sysRoles 角色
     * @param id       id
     * @return Success
     */
    @PostMapping("/save")
    @ResponseBody
    @ApiOperation(value = "【S2003】保存角色基本信息", notes = "保存角色基本信息")
    @ApiOperationSupport(order = 3)
    @Log(value = "保存角色信息（基本信息）", type = "1")
    public Success saveRoleInfo(SysRoles sysRoles, String id) {
        if (StringUtils.isNotBlank(id)) {
            System.err.println("修改");
            sysRolesService.updateByPrimaryKey(sysRoles);
        } else {
            System.err.println("新增");
            sysRoles.setId(UUID.randomUUID().toString().replace("-", ""));
            sysRolesService.save(sysRoles);
        }
        return Success.success();
    }

    /**
     * 【API】-----【S2004】
     * 保存角色-菜单关联
     *
     * @return Success
     */
    @PostMapping("/saveRoleMenus")
    @ResponseBody
    @ApiOperation(value = "【S2004】保存角色和菜单的关联关系", notes = "保存角色和菜单的关联关系")
    @ApiOperationSupport(order = 4)
    @ApiImplicitParams({
            @ApiImplicitParam(value = "菜单ids(逗号分隔)", name = "muenuids", dataType = "string", required = true),
            @ApiImplicitParam(value = "角色id", name = "roleid", dataType = "string", required = true),
    })
    @Log(value = "保存角色信息（关联信息）", type = "1")
    public Success saveRoleMenuRelation(String checkedids, String roleid) {
        String[] ids = checkedids.split(",");

        //先删除之前的关联关系
        SysRoleMenusExample example = new SysRoleMenusExample();
        example.or().andRoleIdEqualTo(roleid);
        sysRoleMenusService.deleteByExample(example);

        //加入新的关联关系
        for (String id : ids) {
            SysRoleMenus rmMenus = new SysRoleMenus();
            rmMenus.setId(UUID.randomUUID().toString().replace("-", ""));
            rmMenus.setMenuId(id);
            rmMenus.setRoleId(roleid);
            sysRoleMenusService.save(rmMenus);
        }

        return Success.success();
    }


    /**
     * 【API】-----【S2005】
     * 保存角色信息（同时保存权限相关信息）
     *
     * @param sysRoles 角色信息
     * @param menuIds  菜单id
     * @return Success
     */
    @PostMapping(value = "/savePC")
    @ResponseBody
    @ApiOperation(value = "【S2005】保存角色表单信息", notes = "保存角色基本信息，包括与菜单的关联关系")
    @ApiOperationSupport(order = 5)
    @ApiImplicitParams({
            @ApiImplicitParam(value = "菜单ids", name = "menuIds", dataType = "string", required = true),
    })
    @Log(value = "保存角色信息", type = "1")
    public Success saveRoleForm(SysRoles sysRoles, String menuIds) {
        String id = sysRoles.getId();
        if (StringUtils.isNotBlank(id)) {
            sysRolesService.updateByPrimaryKey(sysRoles);
        } else {
            sysRoles.setId(UUID.randomUUID().toString().replace("-", ""));
            sysRolesService.save(sysRoles);
        }

        List<String> aBean = JSON.parseArray(menuIds, String.class);
        // 先删除之前的关联关系
        SysRoleMenusExample example = new SysRoleMenusExample();
        example.or().andRoleIdEqualTo(sysRoles.getId());
        sysRoleMenusService.deleteByExample(example);
        // 绑定新的关联关系
        for (String menuId : aBean) {
            SysRoleMenus rmMenus = new SysRoleMenus();
            rmMenus.setId(UUID.randomUUID().toString().replace("-", ""));
            rmMenus.setMenuId(menuId);
            rmMenus.setRoleId(sysRoles.getId());
            rmMenus.setMenuCode(sysMenusService.selectByPrimaryKey(menuId).getCode());
            sysRoleMenusService.save(rmMenus);
        }
        return Success.success();
    }


    /**
     * 【API】-----【S2006】
     * 根据角色id获取角色关联的菜单信息
     *
     * @param roleId 角色id
     * @return Success
     */
    @PostMapping("/getRoleCheckedIds")
    @ResponseBody
    @ApiOperation(value = "【S2006】根据角色id获取角色关联的菜单信息", notes = "根据角色id获取角色关联的菜单信息")
    @ApiOperationSupport(order = 6)
    @ApiImplicitParams({
            @ApiImplicitParam(value = "角色id", name = "roleId", dataType = "string", required = true),
    })
    @Log(value = "根据角色id获取权限", type = "1")
    public Success getMenuIdsByRoleId(String roleId) {
        List<SysRoleMenus> roleMenuList;
        SysRoleMenusExample e1 = new SysRoleMenusExample();
        e1.createCriteria().andRoleIdEqualTo(roleId);
        roleMenuList = sysRoleMenusService.selectByExample(e1);

        List<String> idList = new ArrayList<>();
        for (SysRoleMenus roleMenus : roleMenuList) {
            idList.add(roleMenus.getMenuId());
        }
        return Success.success(idList);
    }


    /**
     * 【API】-----【S2006】
     * 根据角色id获取角色关联的菜单信息
     *
     * @param roleId 角色id
     * @return Success
     */
    @PostMapping("/getMenuCodesByRoleId")
    @ResponseBody
    @ApiOperation(value = "【S2006】根据角色id获取角色关联的菜单编码", notes = "根据角色id获取角色关联的菜单编码")
    @ApiOperationSupport(order = 6)
    @ApiImplicitParams({
            @ApiImplicitParam(value = "角色id", name = "roleId", dataType = "string", required = true),
    })
    @Log(value = "根据角色id获取权限", type = "1")
    public Success getMenuCodesByRoleId(String roleId) {
        List<SysRoleMenus> roleMenuList;
        SysRoleMenusExample e1 = new SysRoleMenusExample();
        e1.createCriteria().andRoleIdEqualTo(roleId);
        roleMenuList = sysRoleMenusService.selectByExample(e1);

        List<String> idList = new ArrayList<>();
        for (SysRoleMenus roleMenus : roleMenuList) {
            idList.add(roleMenus.getMenuCode());
        }
        return Success.success(idList);
    }


    /**
     * 【API】-----【S2007】
     * 删除单个角色信息
     *
     * @param id 角色id
     * @return Success
     */
    @PostMapping("/delete/{id}")
    @ResponseBody
    @ApiOperation(value = "【S2007】删除单个角色信息", notes = "删除单个角色信息")
    @ApiOperationSupport(order = 7)
    @ApiImplicitParams({
            @ApiImplicitParam(value = "角色主键id", name = "id", dataType = "String", required = true, paramType = "path")
    })
    @Log(value = "删除单个角色信息", type = "1")
    public Success deleteSingle(@PathVariable String id) {
        //角色绑定菜单---不可删除
        //角色绑定用户---不可删除
        //删除 角色表信息
        sysRolesService.deleteByPrimaryKey(id);
        return Success.success();
    }


    /**
     * 【API】-----【S2008】
     * 批量删除角色信息
     *
     * @param ids 角色id
     * @return Success
     */
    @PostMapping("/delete")
    @ResponseBody
    @ApiOperation(value = "【S2008】批量删除角色数据", notes = "批量删除角色数据")
    @ApiOperationSupport(order = 8)
    @ApiImplicitParams({
            @ApiImplicitParam(value = "角色主键ids(多个id逗号分隔)", name = "ids", dataType = "String")
    })
    @Log(value = "批量删除角色信息", type = "1")
    public Success deleteBatch(String ids) {
        // 角色绑定菜单---不可删除
        // 角色绑定用户---不可删除
        // 删除 角色表信息
        String[] idStrings = ids.split(",");
        for (String idString : idStrings) {
            sysRolesService.deleteByPrimaryKey(idString);
        }
        return Success.success();

    }


    /**
     * 获取角色对应的关联关系
     *
     * @param roleid 角色id
     * @return List<Map < String, Object>>
     */
    @PostMapping("/getRoleMenusList")
    @ResponseBody
    @ApiOperation(value = "【S2009】根据角色id获取菜单树形结构数据", notes = "根据角色id获取菜单树形结构数据")
    @ApiOperationSupport(order = 9)
    @ApiImplicitParams({
            @ApiImplicitParam(value = "roleid", name = "roleid", dataType = "String")
    })
    @Log(value = "渲染角色-权限信息", type = "1")
    public List<Map<String, Object>> getRoleMenusList(String roleid) {

        List<Map<String, Object>> resultList;

        //获取所有菜单列表
        SysMenusExample e2 = new SysMenusExample();
        e2.setOrderByClause("order_no asc");
        List<SysMenus> menuList = sysMenusService.selectByExample(e2);

        List<SysRoleMenus> roleMenus = new ArrayList<>();
        //查询角色对应的关联关系表
        SysRoleMenusExample example2 = new SysRoleMenusExample();
        if (StringUtils.isNotBlank(roleid)) {
            example2.or().andRoleIdEqualTo(roleid);
            roleMenus = sysRoleMenusService.selectByExample(example2);
        }

        List<String> checkIds = new ArrayList<>();

        for (SysRoleMenus s : roleMenus) {
            checkIds.add(s.getMenuId());
        }
        resultList = CmTreeUtils.getCheckedTreeList(menuList, checkIds);

        return resultList;
    }


}
